from department.models import Department, DepartmentRole, Work, DepartmentParticipate, DepartmentEmpower
from user.models import User
from department.utils.member import add_department_member
from pms.common.utils import has_permissions, flatten_view, has_one_of_permissions
from pms.common.views import PermissionDeny


def has_department_permissions(uid, did, permissions):
    """ 用户 uid 在部门 did 中是否拥有 permissions 中的所有权限 """
    user = User.objects.get(id=uid)
    department = Department.objects.get(id=did)
    role = Work.objects.get(uid=user, rid__did=department).rid
    empowered_permissions = [empower.pid_id for empower in DepartmentEmpower.objects.filter(rid=role)]
    if 1 in empowered_permissions:  # 1-所有部门权限
        return True
    return has_permissions(permissions, empowered_permissions)


def has_one_of_department_permissions(uid, did, permissions):
    """ 用户 uid 在部门 did 中是否拥有 permissions 中的至少一个权限 """
    user = User.objects.get(id=uid)
    department = Department.objects.get(id=did)
    role = Work.objects.get(uid=user, rid__did=department).rid
    empowered_permissions = [empower.pid_id for empower in DepartmentEmpower.objects.filter(rid=role)]
    if 1 in empowered_permissions:  # 1-所有部门权限
        return True
    return has_one_of_permissions(permissions, empowered_permissions)


def assert_department_permissions(uid, did, permissions):
    """ 若用户 uid 在部门 did 中没有拥有 permissions 中的所有权限则抛出 PermissionDeny 错误 """
    if not has_department_permissions(uid, did, permissions):
        raise PermissionDeny


def assert_one_of_department_permissions(uid, did, permissions):
    """ 若用户 uid 在部门 did 中没有拥有 permissions 中的至少一个权限则抛出 PermissionDeny 错误 """
    if not has_one_of_department_permissions(uid, did, permissions):
        raise PermissionDeny


def department_view(department):
    assert isinstance(department, Department)
    view = {
        'id': department.id,
        'name': department.name,
        'detail': department.detail,
        'members': [{
            'id': work.uid.id,
            'name': work.uid.name,
            'annotation': work.annotation,
            'role': {
                'id': work.rid.id,
                'name': work.rid.name
            }
        } for work in Work.objects.filter(rid__did=department).order_by('uid__id')],
        'projects': [{
            'id': department_participate.pid.id,
            'name': department_participate.pid.name
        } for department_participate in DepartmentParticipate.objects.filter(did=department)]
    }
    return view


def create_department(name, user, detail=''):
    assert isinstance(name, str)
    assert isinstance(user, User)
    department = Department(name=name, detail=detail)
    department_role1 = DepartmentRole(did=department, name='组长')
    department_role2 = DepartmentRole(did=department, name='副组长')
    department_role3 = DepartmentRole(did=department, name='成员')
    department_empower = DepartmentEmpower(rid=department_role1, pid_id=1)  # 授予组长所有权限
    department_empower2 = DepartmentEmpower(rid=department_role2, pid_id=2)
    department_empower3 = DepartmentEmpower(rid=department_role2, pid_id=3)
    department.save()
    department_role1.save()
    department_role2.save()
    department_role3.save()
    department_empower.save()
    department_empower2.save()
    department_empower3.save()
    add_department_member(department, department_role1, user, '')
    return department


def update_department(department, view):
    assert isinstance(department, Department)
    department.__dict__.update(**flatten_view(view, {
        'name': 'name',
        'detail': 'detail'
    }))
    department.save()
    return department


def list_departments(user):
    """ 返回 user 任职的所有部门的 QuerySet """
    return Department.objects.filter(departmentrole__work__uid=user)
